#!/usr/bin/env python2.5

##############################################################################################
#
#    LocateME! - Finds location of user in a specific building using contextual information
#    Copyright (C) <2009>  <Kattie Tay>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>
#
##############################################################################################


# Import packages
import pygtk
pygtk.require('2.0')
import gtk
import hildon
import pango
import re
import gps_funcs
import wlan_funcs
import results_GUI
import db_funcs


# Initialize global variables
geocode = 0
lat_long_label_str = ""


class mainGUI(hildon.Program):
    
    # Initialize GUI
    def __init__(self):
            
        hildon.Program.__init__(self)
        
        # Retrieve last saved GPS data and store as global variable geocode
        # Only store 3 decimal places
        global geocode, lat_long_label_str
        latitude = gps_funcs.gps_get_latitude()
        longitude = gps_funcs.gps_get_longitude()
        geocode = "%.3f, %.3f" %(latitude, longitude)
        
        
        # --- Main Window --- 
        # Create main window
        self.main_window = hildon.Window()
        self.main_window.connect("destroy", self.destroy_cb, None)  
        self.main_window.set_border_width(10)
        self.main_window.set_title("LocateME!")
        
        # Create table layout
        table_layout = gtk.Table(10, 10, True)
        self.main_window.add(table_layout)
        
        
        # --- Welcome label --- 
        # Create label to display welcome message
        welcome_label_str = " Welcome to LocateME! "
        welcome_label = gtk.Label(welcome_label_str)
        # Set label attributes
        welcome_label_attr = pango.AttrList()
        fg_color = pango.AttrForeground(65535, 0, 0, 0, len(welcome_label_str))
        bg_color = pango.AttrBackground(40000, 40000, 40000, 0, len(welcome_label_str))
        size = pango.AttrSize(40000, 0, -1)
        weight = pango.AttrWeight(pango.WEIGHT_BOLD, 0, len(welcome_label_str))
        welcome_label_attr.insert(fg_color)
        welcome_label_attr.insert(bg_color)
        welcome_label_attr.insert(size)
        welcome_label_attr.insert(weight)
        welcome_label.set_attributes(welcome_label_attr)
        welcome_label.set_alignment(0.4, 1)
        # Set position of widget in window and show it
        table_layout.attach(welcome_label, 1, 9, 0, 3, gtk.EXPAND, gtk.EXPAND, 5, 5)
        welcome_label.show()
        
        
        # --- Last GPS location label --- 
        # Create label to display last GPS location
        last_gpsloc_label_str = "Your last GPS location is:" 
        self.last_gpsloc_label = gtk.Label(last_gpsloc_label_str)
        self.last_gpsloc_label.set_alignment(0.5, 0)
        # Set position of widget in window and show it
        table_layout.attach(self.last_gpsloc_label, 1, 9, 3, 4, gtk.FILL, gtk.EXPAND, 5, 5)
        self.last_gpsloc_label.show()
        
        
        # --- Geocode values label --- 
        # Create label to display latitude and longitude        
        lat_long_label_str = "Latitude = %.3f, Longitude = %.3f" %(latitude, longitude)
        self.lat_long_label = gtk.Label(lat_long_label_str)
        self.lat_long_label.set_alignment(0.5, 1)
        # Set position of widget in window and show it
        table_layout.attach(self.lat_long_label, 1, 9, 5, 6, gtk.FILL, gtk.EXPAND, 5, 5)
        self.lat_long_label.show()
        
        
        # --- Location name label ---
        # Create label to display location name
        loc_name_label_str = db_funcs.db_get_loc_name(geocode)
        self.loc_name_label = gtk.Label(loc_name_label_str)
        # Set label attributes
        loc_name_label_attr = pango.AttrList()
        fg_color = pango.AttrForeground(0, 0, 65535, 0, len(loc_name_label_str))
        size = pango.AttrSize(30000, 0, -1)
        weight = pango.AttrWeight(pango.WEIGHT_BOLD, 0, len(loc_name_label_str))
        loc_name_label_attr.insert(fg_color)
        loc_name_label_attr.insert(size)
        loc_name_label_attr.insert(weight)
        self.loc_name_label.set_attributes(loc_name_label_attr)
        self.loc_name_label.set_alignment(0.5, 0.5)
        # Set position of widget in window and show it
        table_layout.attach(self.loc_name_label, 1, 9, 4, 5, gtk.FILL, gtk.EXPAND, 5, 5)
        self.loc_name_label.show()
    
        
        # --- Change location button ---
        # Create button to change location
        change_loc_button_str = " Change Location "
        self.change_loc_button = gtk.Button(change_loc_button_str)
        self.change_loc_button.connect("clicked", self.change_loc_cb, None)
        self.change_loc_button.set_alignment(0.5, 0.5)
        # Set button label attributes
        change_loc_label = self.change_loc_button.child
        change_loc_label.modify_font(pango.FontDescription("Bold"))
        # Set position of widget in window and show it
        table_layout.attach(self.change_loc_button, 0, 4, 7, 10, gtk.FILL, gtk.FILL, 15, 20)
        self.change_loc_button.show()
        
        
        # --- LocateMe button ---
        # Create button to locate user
        locate_user_button_str = " LocateME! "
        self.locate_user_button = gtk.Button(locate_user_button_str)
        self.locate_user_button.connect("clicked", self.locate_user_cb, None)
        self.locate_user_button.set_alignment(0.5, 0.5)
        # Set button label attributes
        locate_user_label = self.locate_user_button.child
        locate_user_label.modify_font(pango.FontDescription("Bold 24"))
        # Set position of widget in window and show it    
        table_layout.attach(self.locate_user_button, 4, 7, 7, 10, gtk.FILL, gtk.FILL, 15, 20)
        self.locate_user_button.show()
        
        
        # --- Add Location button
        # Create button to add location
        add_loc_button_str = " Add Location "
        self.add_loc_button = gtk.Button(add_loc_button_str)
        self.add_loc_button.connect("clicked", self.add_loc_cb, None)
        self.add_loc_button.set_alignment(0.5, 0.5)
        # Set button label attributes
        add_loc_label = self.add_loc_button.child
        add_loc_label.modify_font(pango.FontDescription("Bold"))
        # Set position of widget in window and show it    
        table_layout.attach(self.add_loc_button, 7, 10, 7, 10, gtk.FILL, gtk.FILL, 15, 20)
        self.add_loc_button.show()
        
        
        # --- Menu ---
        # Set up the menu bar
        self.options_menu = gtk.Menu()
        
        # Create menu items
        self.add_loc_menuitem = gtk.MenuItem("Add Location")
        self.change_loc_menuitem = gtk.MenuItem("Change Location")
        self.edit_data_menuitem = gtk.MenuItem("Edit Data")
        self.exit_menuitem = gtk.MenuItem("Exit")
                            
        self.options_menu.append(self.add_loc_menuitem)
        self.options_menu.append(self.change_loc_menuitem)
        self.options_menu.append(self.edit_data_menuitem)
        self.options_menu.append(self.exit_menuitem)
                        
        self.add_loc_menuitem.connect_object("activate", self.add_loc_cb, None)
        self.change_loc_menuitem.connect_object("activate", self.change_loc_cb, None)
        self.edit_data_menuitem.connect_object("activate", self.edit_data_cb, None)
        self.exit_menuitem.connect_object("activate", self.destroy_cb, None)
        
        self.add_loc_menuitem.show()
        self.change_loc_menuitem.show()
        self.edit_data_menuitem.show()
        self.exit_menuitem.show()
        
        self.main_window.set_menu(self.options_menu)
        
        
        # --- Call disable_buttons_check function ---
        # Check which buttons to enable or disable
        self.disable_buttons_check()
        
        
        # Show main window
        table_layout.show()
        self.main_window.show()   
        
        
    # Get no value selected dialog box
    def get_none_sel_dialog(self):
        # Create no value selected error dialog window
        none_sel_dialog = gtk.Dialog("Error!", self.main_window, gtk.DIALOG_MODAL, (gtk.STOCK_OK, gtk.RESPONSE_OK))
        none_sel_dialog_label = gtk.Label("No value selected!")
        none_sel_dialog.vbox.pack_start(none_sel_dialog_label, True, True, 0)
        none_sel_dialog.set_has_separator(False)
        none_sel_dialog.show_all()
        
        # Run no value selected error dialog window
        none_sel_dialog_result = none_sel_dialog.run()
        # Destroy no value selected erorr dialog window when OK is pressed
        if none_sel_dialog_result == gtk.RESPONSE_OK:
            none_sel_dialog.destroy()
        
        
    # Get no internet connection detected dialog box
    def get_no_conn_dialog(self):
        # Create no connection error dialog window
        self.no_conn_dialog = gtk.Dialog("No internet connection!", self.main_window, gtk.DIALOG_MODAL, (gtk.STOCK_OK,
                                             gtk.RESPONSE_OK))
        no_conn_dialog_label = gtk.Label("Internet connection is required to proceed. Please connect to the internet.")
        no_conn_dialog_label.set_line_wrap(True)
        self.no_conn_dialog.vbox.pack_start(no_conn_dialog_label, True, True, 0)
        no_conn_dialog_label.show()
        self.no_conn_dialog.set_has_separator(False)
        
        # Run no connection error dialog window
        noconn_result = self.no_conn_dialog.run()
        # Destroy no connection error dialog window when OK is pressed
        if noconn_result == gtk.RESPONSE_OK:
            self.no_conn_dialog.destroy()
    
    
    # Perform check to determine which buttons to enable or disable
    def disable_buttons_check(self):
        unknown = re.search('Unknown', self.loc_name_label.get_text())
        # If location name does not exist in db
        if unknown:
            # Disable LocateMe button
            self.locate_user_button.set_sensitive(False)
            # Enable Add Location button and menu item
            self.add_loc_button.set_sensitive(True)
            self.add_loc_menuitem.set_sensitive(True)
        else:
            # Disable Add Location button and menu item
            self.add_loc_button.set_sensitive(False)
            self.add_loc_menuitem.set_sensitive(False)
            # Enable LocateMe button
            self.locate_user_button.set_sensitive(True)


    # Get list of locations from database and allows user to select from them
    def get_loc_list_combobox(self):
        # Create select location dialog window
        self.loc_list_dialog = gtk.Dialog("Select location:", self.main_window, gtk.DIALOG_MODAL, 
                                          (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, 
                                           gtk.RESPONSE_CANCEL))
        self.loc_list_dialog.set_size_request(250, 130)
        
        # Create combobox within select location dialog window
        self.loc_list_combobox = gtk.combo_box_new_text()
        # Fill combobox list with values from db
        loc_list = db_funcs.db_get_loc_list()
        self.loc_list_combobox.append_text('Select a location:')
        for i in range(0,len(loc_list)):
            self.loc_list_combobox.append_text(loc_list[i])
        self.loc_list_combobox.set_active(0)
        
        self.loc_list_dialog.vbox.pack_start(self.loc_list_combobox, True, False, 10)
        self.loc_list_combobox.show()
        
        # Run select location dialog window
        loclist_result = self.loc_list_dialog.run()
        # Destroy select location dialog window when Cancel button is pressed
        if loclist_result == gtk.RESPONSE_CANCEL:
            self.loc_list_dialog.destroy()
        # Get selected value from combolist when OK is pressed
        elif loclist_result == gtk.RESPONSE_OK:
            # Get selected value
            model = self.loc_list_combobox.get_model()
            index = self.loc_list_combobox.get_active()
            # If a value was selected, return it and destroy select location dialog window
            if index:
                self.loc_list_dialog.destroy()
                return model[index][0]
            # If no value selected, destroy select location dialog window
            else:
                self.loc_list_dialog.destroy()


    # Callback function for LocateMe button
    def locate_user_cb(self, widget, data=None):
        # Get connection status
        connected = wlan_funcs.wlan_check_conn_status()
        if not connected:
            # Display no connection error
            self.get_no_conn_dialog()
        else:
            # Get location name
            loc_name = self.loc_name_label.get_text()
            # Open results window and pass in loc_name as parameter
            open_results = results_GUI.show_window(loc_name)    
            # Hide main window
            self.main_window.hide()    
    
    
    # Callback function for Change Location button
    def change_loc_cb(self, widget, data=None):
        # Call function to display Change Location window
        loc_name = self.get_loc_list_combobox()
        # If valid value returned
        if loc_name:
            # Update main window with new values
            self.loc_name_label.set_text(loc_name)
            self.last_gpsloc_label.set_text("Your chosen location is:")
            self.lat_long_label.set_text("")
        # Call function to check which buttons to enable or disable
        self.disable_buttons_check()
            
            
    # Callback function for Add Location button
    def add_loc_cb(self, widget, data=None):
        global geocode
        # Get connection status
        connected = wlan_funcs.wlan_check_conn_status()
        if not connected:
            # Display no connection error
            self.get_no_conn_dialog()
        else:
            # Create add location dialog window
            self.add_loc_dialog = gtk.Dialog("Add new location:", self.main_window, gtk.DIALOG_MODAL, 
                                              ("Browse", gtk.RESPONSE_APPLY, "Add", gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, 
                                               gtk.RESPONSE_CANCEL))
            
            # Retrieve essid value of current connection
            essid = wlan_funcs.wlan_get_conn_essid()
            str = "Geocode = %s\nESSID = %s" %(geocode, essid)
            str = str.strip()
            add_loc_dialog_label = gtk.Label(str)
            self.add_loc_dialog.vbox.pack_start(add_loc_dialog_label, True, True, 5)
            add_loc_dialog_label.set_alignment(0, 0.5)
            add_loc_dialog_label.show()
            
            # Create label
            loc_label = gtk.Label("Location:")
            self.add_loc_dialog.vbox.pack_start(loc_label, True, True, 5)
            loc_label.set_alignment(0, 0.5)
            loc_label.show()
            
            # Create text entry field
            loc_name_entry = gtk.Entry()
            self.add_loc_dialog.vbox.pack_start(loc_name_entry, True, True, 5)
            loc_name_entry.show()
            
            while True:
                # Run add location dialog box
                addloc_result = self.add_loc_dialog.run()
                # Exit infinite loop when Cancel is pressed
                if addloc_result == gtk.RESPONSE_CANCEL:
                    break
                # Display location list combobox when Browse is pressed
                elif addloc_result == gtk.RESPONSE_APPLY:
                    loc_name = self.get_loc_list_combobox()
                    # If valid value returned, set text entry field to value returned
                    if loc_name:
                        loc_name_entry.set_text(loc_name)
                # Add location to db when Add is pressed
                elif addloc_result == gtk.RESPONSE_ACCEPT:
                    loc_name = loc_name_entry.get_text()
                    loc_name = loc_name.strip()
                    # If description field is empty, display error message
                    if loc_name == "":
                        # Create description empty error dialog window
                        self.empty_field_dialog = gtk.Dialog("Error!", self.main_window, gtk.DIALOG_MODAL, 
                                                             (gtk.STOCK_OK, gtk.RESPONSE_OK))
                        empty_field_dialog_label = gtk.Label("Please enter or select a location name.")
                        empty_field_dialog_label.set_line_wrap(True)
                        self.empty_field_dialog.vbox.pack_start(empty_field_dialog_label, True, True, 0)
                        self.empty_field_dialog.set_has_separator(False)
                        self.empty_field_dialog.show_all()
                        
                        # Run description empty error dialog window 
                        emptyfield_result = self.empty_field_dialog.run()
                        # Destroy description empty error dialog window when OK is pressed
                        if emptyfield_result == gtk.RESPONSE_OK:
                            self.empty_field_dialog.destroy()
                    
                    # If description field not empty
                    else:
                        # Check if description already exists in db
                        exists = 0
                        loc_list = db_funcs.db_get_loc_list()
                        for i in range(0, len(loc_list)):
                            match = re.match(loc_name, loc_list[i])
                            # If description exists
                            if match:
                                exists = 1
                                # Add geocode value to existing location
                                db_funcs.db_add_geocode_to_loc(loc_name, geocode)
                                break
                        # If description does not exist
                        if not exists:
                            # Add location name, geocode value and essid to db
                            db_funcs.db_add_new_loc(loc_name, geocode, essid)
                        break

            # Update main window
            loc_name = db_funcs.db_get_loc_name(geocode)
            self.loc_name_label.set_text(loc_name)
            self.disable_buttons_check()
            # Destroy add location dialog window
            self.add_loc_dialog.destroy()
        
    
    # Callback function for Edit Data menu item
    def edit_data_cb(self, widget, data=None):
        global geocode, lat_long_label_str
        # Create edit location dialog window
        edit_data_dialog = gtk.Dialog("Locations", self.main_window, gtk.DIALOG_MODAL,
                                      ("Edit", gtk.RESPONSE_OK, "Delete", gtk.RESPONSE_ACCEPT, 
                                       gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
        edit_data_dialog.set_size_request(400, 250)
        # Create list widget within edit location dialog window
        loc_liststore = gtk.ListStore(str)
        # Get list of all locations in db and display in list
        loc_list = db_funcs.db_get_loc_list()
        for i in range(0, len(loc_list)):
            loc_liststore.append(['%s' %loc_list[i]])
        loc_listview = gtk.TreeView(loc_liststore)
        loc_column = gtk.TreeViewColumn('Location')
        loc_listview.append_column(loc_column)
        loc_cell = gtk.CellRendererText()
        loc_column.pack_start(loc_cell, True)
        loc_column.add_attribute(loc_cell, 'text', 0)
    
        loc_listsel = loc_listview.get_selection()
        # Allow only one value to be selected at any given time
        loc_listsel.set_mode(gtk.SELECTION_SINGLE)
        
        # Create scrolled window for list
        scroll_window = gtk.ScrolledWindow()
        scroll_window.add(loc_listview)
    
        edit_data_dialog.vbox.pack_start(scroll_window, True, True, 0)
        scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        loc_listview.show()
        scroll_window.show()

        while True:
            # Run edit location dialog window
            loc_list_result = edit_data_dialog.run()
            # Exit infinite loop when Cancel is pressed
            if loc_list_result == gtk.RESPONSE_CANCEL:
                break
            # Display geocode values for selected location when Edit is pressed
            elif loc_list_result == gtk.RESPONSE_OK:
                # Get selection
                (model, iter) = loc_listsel.get_selected()
                # If none selected
                if iter == None:
                    # Display error message
                    self.get_none_sel_dialog()
                else:
                    # Get value of selection
                    loc = model.get_value(iter, 0)
                    # Create edit location geocode dialog window
                    edit_loc_geocode_dialog = gtk.Dialog("Geocodes-Lat/Long", self.main_window, gtk.DIALOG_MODAL,
                                                          ("Delete", gtk.RESPONSE_ACCEPT, 
                                                           gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
                    edit_loc_geocode_dialog.set_size_request(300, 250)
                    # Create list widget within edit location geocode dialog window
                    loc_geocode_liststore = gtk.ListStore(str)
                    # Get list of geocode values corresponding to selected location and add to list widget
                    loc_geocode_list = db_funcs.db_get_loc_geocode_list(loc)
                    for i in range(0, len(loc_geocode_list)):
                        loc_geocode_liststore.append(['%s' %loc_geocode_list[i]])
                    loc_geocode_listview = gtk.TreeView(loc_geocode_liststore)
                    loc_geocode_column = gtk.TreeViewColumn()
                    loc_geocode_listview.append_column(loc_geocode_column)
                    loc_geocode_cell = gtk.CellRendererText()
                    loc_geocode_column.pack_start(loc_geocode_cell, True)
                    loc_geocode_column.set_attributes(loc_geocode_cell, text=0)
                
                    loc_geocode_listsel = loc_geocode_listview.get_selection()
                    # Allow only one value to be selected at any given time
                    loc_geocode_listsel.set_mode(gtk.SELECTION_SINGLE)
                    
                    # Create scrolled window for list
                    scroll_window = gtk.ScrolledWindow()
                    scroll_window.add(loc_geocode_listview)
                
                    edit_loc_geocode_dialog.vbox.pack_start(scroll_window, True, True, 0)
                    scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
                    loc_geocode_listview.show()
                    scroll_window.show()
                    
                    while True:
                        # Run edit location geocode dialog window
                        edit_geocode = edit_loc_geocode_dialog.run()
                        # Exit infinite loop when Cancel is pressed
                        if edit_geocode == gtk.RESPONSE_CANCEL:
                            break
                        # Delete selected value when Delete is pressed
                        elif edit_geocode == gtk.RESPONSE_ACCEPT:
                            # Get selection
                            (geocode_model, geocode_iter) = loc_geocode_listsel.get_selected()
                            # If none selected
                            if geocode_iter == None:
                                # Display error message
                                self.get_none_sel_dialog()
                            else:
                                # Get value of selection
                                geocode = geocode_model.get_value(geocode_iter, 0)
                                # Create delete confirmation dialog window
                                confirm_del_dialog = gtk.Dialog("Delete?", self.main_window, gtk.DIALOG_MODAL, (gtk.STOCK_YES, gtk.RESPONSE_YES,
                                                                                                      gtk.STOCK_NO, gtk.RESPONSE_NO))
                                confirm_del_dialog_label = gtk.Label("Are you sure you want to delete this?")
                                confirm_del_dialog.vbox.pack_start(confirm_del_dialog_label, True, True, 0)
                                confirm_del_dialog.set_has_separator(False)
                                confirm_del_dialog.show_all()
                                
                                # Run delete confirmation dialog window
                                confirm_del_result = confirm_del_dialog.run()
                                # Remove value from db and list when Yes is pressed
                                if confirm_del_result == gtk.RESPONSE_YES:
                                    del_loc = db_funcs.db_remove_geocode(loc, geocode)
                                    geocode_model.remove(geocode_iter)
                                    confirm_del_dialog.destroy()
                                    if del_loc == True:
                                        model.remove(iter)
                                # Destroy delete confirmation dialog window when No is pressed
                                elif confirm_del_result == gtk.RESPONSE_NO:
                                    confirm_del_dialog.destroy()
                    # Destroy edit location geocode dialog window
                    edit_loc_geocode_dialog.destroy()
            
            # Delete selected location from db and list when Delete is pressed            
            elif loc_list_result == gtk.RESPONSE_ACCEPT:
                # Get selection
                (model, iter) = loc_listsel.get_selected()
                # If none selected
                if iter == None:
                    # Display error message
                    self.get_none_sel_dialog()
                else:
                    # Create delete confirmation dialog window
                    confirm_del_dialog = gtk.Dialog("Delete?", self.main_window, gtk.DIALOG_MODAL, (gtk.STOCK_YES, gtk.RESPONSE_YES,
                                                                                                  gtk.STOCK_NO, gtk.RESPONSE_NO))
                    confirm_del_dialog_label = gtk.Label("Are you sure you want to delete this?")
                    confirm_del_dialog.vbox.pack_start(confirm_del_dialog_label, True, True, 0)
                    confirm_del_dialog.set_has_separator(False)
                    confirm_del_dialog.show_all()
                    
                    # Run delete confirmation dialog window
                    confirm_del_result = confirm_del_dialog.run()
                     # Remove value from db and list when Yes is pressed
                    if confirm_del_result == gtk.RESPONSE_YES:
                        db_funcs.db_remove_loc(model.get_value(iter, 0))
                        model.remove(iter)
                        confirm_del_dialog.destroy()
                    # Destroy delete confirmation dialog window when No is pressed
                    elif confirm_del_result == gtk.RESPONSE_NO:
                        confirm_del_dialog.destroy()
        
        # Update main window
        loc_name = db_funcs.db_get_loc_name(geocode)
        self.loc_name_label.set_text(loc_name)
        self.last_gpsloc_label.set_text("Your last GPS location is:")
        self.lat_long_label.set_text(lat_long_label_str)
        self.disable_buttons_check()
        # Destroy edit location dialog window
        edit_data_dialog.destroy()


    # Callback function for Exit menu item
    def destroy_cb(self, widget, data=None):
        # Call function to close db
        db_funcs.db_close()
        # Exit application
        gtk.main_quit()
               
               
    # Run application
    def run(self): 
        gtk.main() 


# Initialization
if __name__ == "__main__":
    db_funcs.db_init()
    gps_funcs.gps_init()  
    wlan_funcs.wlan_init_connection()
    app = mainGUI() 
    app.run()
    
    